using Simple.Contracts.Contracts;
using Simple.Contracts.Models;
using Simple.Contracts.Models.Common;
using Simple.Contracts.Models.Common.Page;
using Simple.Repository;
using Simple.Repository.SimpleEntitys;
using Simple.Services;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Simple.Services.Services
{
    /// <summary>
    /// 角色服务实现
    /// </summary>
    public class RoleService : BaseService, IRoleService
    {
        public RoleService(FreeSqlCloud freeSqlCloud, CurrentAccount currentAccount) : base(freeSqlCloud, currentAccount)
        {
        }

        /// <summary>
        /// 获取角色列表
        /// </summary>
        /// <param name="input">角色列表输入参数</param>
        /// <returns>角色列表</returns>
        public async Task<Result<List<RoleDto>>> List(RoleListInput input)
        {
            var list = await _simpleFreeSql.Select<Role>()
                    .Where(x => x.CompanyId == _currentAccount.CompanyId && x.IsDelete == 0)
                    .WhereIf(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name!))
                    .ToListAsync(x => new RoleDto()
                    {
                        Id = x.Id,
                        Name = x.Name,
                        CompanyId = x.CompanyId,
                        CreateTime = x.CreateTime
                    });

            return Result<List<RoleDto>>.Success(list);
        }

        /// <summary>
        /// 保存角色信息
        /// </summary>
        /// <param name="input">角色保存输入参数</param>
        /// <returns>保存结果</returns>
        public async Task<Result<long>> Save(RoleSaveInput input)
        {
            try
            {
                if (string.IsNullOrEmpty(input.Name))
                {
                    return Result<long>.FriendlyReminder("角色名称不能为空");
                }

                long roleId = 0;
                if (input.Id.HasValue && input.Id != 0)
                {
                    // 更新角色
                    var role = await _simpleFreeSql.Select<Role>()
                        .Where(x => x.Id == input.Id.Value && x.CompanyId == _currentAccount.CompanyId && x.IsDelete == 0)
                        .FirstAsync();

                    if (role == null)
                    {
                        return Result<long>.FriendlyReminder("该角色不存在或已被删除");
                    }

                    // 检查角色名称是否重复
                    var exists = await _simpleFreeSql.Select<Role>()
                        .Where(x => x.Name == input.Name && x.Id != input.Id.Value && x.CompanyId == _currentAccount.CompanyId && x.IsDelete == 0)
                        .AnyAsync();

                    if (exists)
                    {
                        return Result<long>.FriendlyReminder("角色名称已存在");
                    }

                    role.Name = input.Name;
                    role.UpdateTime = DateTime.Now;
                    role.UpdateBy = _currentAccount.EmployeeId;

                    await _simpleFreeSql.Update<Role>().SetSource(role).ExecuteAffrowsAsync();
                    roleId = role.Id;
                }
                else
                {
                    // 新增角色
                    // 检查角色名称是否重复
                    var exists = await _simpleFreeSql.Select<Role>()
                        .Where(x => x.Name == input.Name && x.CompanyId == _currentAccount.CompanyId && x.IsDelete == 0)
                        .AnyAsync();

                    if (exists)
                    {
                        return Result<long>.FriendlyReminder("角色名称已存在");
                    }

                    var role = new Role
                    {
                        Name = input.Name,
                        CompanyId = _currentAccount.CompanyId,
                        CreateTime = DateTime.Now,
                        CreateBy = _currentAccount.EmployeeId,
                        UpdateTime = DateTime.Now,
                        UpdateBy = _currentAccount.EmployeeId,
                        IsDelete = 0
                    };

                    roleId = await _simpleFreeSql.Insert<Role>(role).ExecuteIdentityAsync();
                }

                // 删除该角色原有的所有权限关联
                await _simpleFreeSql.Update<RolePermission>()
                    .Set(x => x.IsDelete, 1)
                    .Set(x => x.UpdateTime, DateTime.Now)
                    .Set(x => x.UpdateBy, _currentAccount.EmployeeId)
                    .Where(x => x.RoleId == roleId && x.CompanyId == _currentAccount.CompanyId)
                    .ExecuteAffrowsAsync();

                // 添加新的权限关联
                if (input.halfSelectedPermissionIds != null && input.halfSelectedPermissionIds.Count > 0)
                {
                    var now = DateTime.Now;
                    var rolePermissions = input.halfSelectedPermissionIds.Select(permissionId => new RolePermission
                    {
                        CompanyId = _currentAccount.CompanyId,
                        RoleId = (int)roleId,
                        PermissionId = permissionId,
                        CreateTime = now,
                        CreateBy = _currentAccount.EmployeeId,
                        UpdateTime = now,
                        UpdateBy = _currentAccount.EmployeeId,
                        IsDelete = 0,
                        SelectedStatus = "半选中"
                    }).ToList();
                    await _simpleFreeSql.Insert<RolePermission>(rolePermissions).ExecuteAffrowsAsync();
                }
                // 添加新的权限关联
                if (input.selectAllPermissionIds != null && input.selectAllPermissionIds.Count > 0)
                {
                    var now = DateTime.Now;
                    var rolePermissions = input.selectAllPermissionIds.Select(permissionId => new RolePermission
                    {
                        CompanyId = _currentAccount.CompanyId,
                        RoleId = (int)roleId,
                        PermissionId = permissionId,
                        CreateTime = now,
                        CreateBy = _currentAccount.EmployeeId,
                        UpdateTime = now,
                        UpdateBy = _currentAccount.EmployeeId,
                        IsDelete = 0,
                        SelectedStatus = "全选中"
                    }).ToList();
                    await _simpleFreeSql.Insert<RolePermission>(rolePermissions).ExecuteAffrowsAsync();
                }

                return Result<long>.Success(roleId);
            }
            catch (Exception ex)
            {
                return Result<long>.FriendlyReminder("保存角色信息失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 删除角色
        /// </summary>
        /// <param name="input">角色删除输入参数</param>
        /// <returns>删除结果</returns>
        public async Task<Result<bool>> Delete(RoleDeleteInput input)
        {
            try
            {
                if (input.Ids == null || input.Ids.Count == 0)
                {
                    return Result<bool>.FriendlyReminder("请选择要删除的角色");
                }

                // 检查角色是否关联了员工
                var hasEmployee = await _simpleFreeSql.Select<RoleEmployee>()
                    .Where(x => input.Ids.Contains(x.RoleId) && x.CompanyId == _currentAccount.CompanyId && x.IsDelete == 0)
                    .AnyAsync();

                if (hasEmployee)
                {
                    return Result<bool>.FriendlyReminder("所选角色已关联员工，无法删除");
                }

                // 软删除角色
                await _simpleFreeSql.Update<Role>()
                    .Set(x => x.IsDelete, 1)
                    .Set(x => x.UpdateTime, DateTime.Now)
                    .Set(x => x.UpdateBy, _currentAccount.EmployeeId)
                    .Where(x => input.Ids.Contains(x.Id) && x.CompanyId == _currentAccount.CompanyId)
                    .ExecuteAffrowsAsync();

                // 删除角色权限关联
                await _simpleFreeSql.Update<RolePermission>()
                    .Set(x => x.IsDelete, 1)
                    .Set(x => x.UpdateTime, DateTime.Now)
                    .Set(x => x.UpdateBy, _currentAccount.EmployeeId)
                    .Where(x => input.Ids.Contains(x.RoleId) && x.CompanyId == _currentAccount.CompanyId)
                    .ExecuteAffrowsAsync();

                return Result<bool>.Success(true);
            }
            catch (Exception ex)
            {
                return Result<bool>.FriendlyReminder("删除角色失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 获取所有权限树
        /// </summary>
        /// <returns>权限树</returns>
        public async Task<Result<List<PermissionDto>>> GetPermissionTree()
        {
            try
            {
                var permissions = await _simpleFreeSql.Select<SysPermission>().Where(x => x.Version.Contains(_currentAccount.CompanyVersion + "√")).ToListAsync();
                var tree = BuildPermissionTree(permissions, 0);
                return Result<List<PermissionDto>>.Success(tree);
            }
            catch (Exception ex)
            {
                return Result<List<PermissionDto>>.FriendlyReminder("获取权限树失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 获取角色已分配的权限
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <returns>权限Id列表</returns>
        public async Task<Result<List<long>>> GetRolePermissions(int roleId)
        {
            try
            {
                var permissionIds = await _simpleFreeSql.Select<RolePermission>()
                    .Where(x => x.RoleId == roleId && x.CompanyId == _currentAccount.CompanyId && x.IsDelete == 0 && x.SelectedStatus == "全选中")
                    .ToListAsync(x => x.PermissionId);

                return Result<List<long>>.Success(permissionIds);
            }
            catch (Exception ex)
            {
                return Result<List<long>>.FriendlyReminder("获取角色权限失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 构建权限树
        /// </summary>
        /// <param name="permissions">所有权限</param>
        /// <param name="parentId">父级权限Id</param>
        /// <returns>权限树</returns>
        private List<PermissionDto> BuildPermissionTree(List<SysPermission> permissions, long parentId)
        {
            var tree = new List<PermissionDto>();
            var childPermissions = permissions.Where(x => x.ParentId == parentId).OrderBy(x => x.Id).ToList();

            foreach (var permission in childPermissions)
            {
                var dto = new PermissionDto
                {
                    Id = permission.Id,
                    Type = permission.Type,
                    Title = permission.Title,
                    Name = permission.Name,
                    ParentId = permission.ParentId,
                    Children = BuildPermissionTree(permissions, permission.Id),
                    Checked = false,
                    Indeterminate = false
                };
                tree.Add(dto);
            }

            return tree;
        }
    }
}